package com.rustic.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.xy.base.server.po.SysAdmin;
import cn.xy.base.server.service.SysAdminService;
import cn.xy.commons.enums.DisableStatus;
import cn.xy.commons.exception.JzRuntimeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rustic.server.dao.EventActivityDao;
import com.rustic.server.dto.EventActivityUpdateDTO;
import com.rustic.server.enums.CategoryType;
import com.rustic.server.enums.LinkType;
import com.rustic.server.po.Category;
import com.rustic.server.po.EventActivity;
import com.rustic.server.po.Rustic;
import com.rustic.server.po.UserCollectionLink;
import com.rustic.server.po.UserLikeLink;
import com.rustic.server.query.EventActivityAdminListQuery;
import com.rustic.server.query.EventActivityUserListQuery;
import com.rustic.server.service.CategoryService;
import com.rustic.server.service.EventActivityService;
import com.rustic.server.service.RusticService;
import com.rustic.server.service.UserBrowseLinkService;
import com.rustic.server.service.UserCollectionLinkService;
import com.rustic.server.service.UserLikeLinkService;
import com.rustic.server.vo.EventActivityVO;
import com.rustic.server.vo.EventActivityWebVO;
import com.rustic.server.vo.list.EventActivityAdminListVO;
import com.rustic.server.vo.list.EventActivityWebListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * EventActivity对应的服务类实现
 *
 * @author auto
 */

@Slf4j
@Service
public class EventActivityServiceImpl extends ServiceImpl<EventActivityDao, EventActivity> implements EventActivityService {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RusticService rusticService;

    @Autowired
    private SysAdminService sysAdminService;

    @Autowired
    private UserLikeLinkService userLikeLinkService;

    @Autowired
    private UserCollectionLinkService userCollectionLinkService;

    @Autowired
    private UserBrowseLinkService userBrowseLinkService;

    @Override
    public List<EventActivity> listByIdIn(List<Integer> idList) {
        if (CollUtil.isEmpty(idList)) {
            return new ArrayList<>();
        }
        return this.listByIds(idList);
    }

    @Override
    public Map<Integer, EventActivity> mapByIdIn(List<Integer> idList) {
        List<EventActivity> eventActivityList = this.listByIdIn(idList);
        return eventActivityList.stream().collect(Collectors.toMap(EventActivity::getId, b -> b));
    }

    @Override
    public LambdaQueryWrapper<EventActivity> toAdminListWrapper(EventActivityAdminListQuery query) {
        LambdaQueryWrapper<EventActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EventActivity::getRusticId, query.getRusticId());
        queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getName()), EventActivity::getName, query.getName());
        queryWrapper.eq(query.getType() > 0, EventActivity::getType, query.getType());
        queryWrapper.gt(query.getStartStartTime() != null, EventActivity::getStartTime, query.getStartStartTime());
        queryWrapper.lt(query.getEndStartTime() != null, EventActivity::getStartTime, query.getEndStartTime());
        queryWrapper.gt(query.getStartEndTime() != null, EventActivity::getEndTime, query.getStartEndTime());
        queryWrapper.lt(query.getEndEndTime() != null, EventActivity::getEndTime, query.getEndEndTime());
        queryWrapper.eq(query.getStatus() > 0, EventActivity::getStatus, query.getStatus());
        queryWrapper.orderByDesc(EventActivity::getSort);
        queryWrapper.orderByDesc(EventActivity::getUpdateTime);
        return queryWrapper;
    }

    @Override
    public List<EventActivityAdminListVO> toAdminListVo(List<EventActivity> eventActivityList) {
        List<EventActivityAdminListVO> results = new ArrayList<>();
        // 获取分类
        List<Category> categoryList = categoryService.listByType(CategoryType.ACTIVITY);
        Map<Integer, Category> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, b -> b));
        for (EventActivity eventActivity : eventActivityList) {
            EventActivityAdminListVO eventActivityAdminListVO = new EventActivityAdminListVO(eventActivity);
            Category category = categoryMap.get(eventActivity.getType());
            eventActivityAdminListVO.setTypeName(category != null ? category.getName() : "");
            results.add(eventActivityAdminListVO);
        }
        return results;
    }

    @Override
    public List<EventActivityWebListVO> toWebListVo(List<EventActivity> eventActivityList, int userId) {
        List<Integer> eventActivityIdList = eventActivityList.stream().map(EventActivity::getId).collect(Collectors.toList());
        Map<Integer, Long> likeCountMap = userLikeLinkService.mapByTargetIdAndType(eventActivityIdList, LinkType.ACTIVITY);
        Map<Integer, Long> collectionCountMap = userCollectionLinkService.mapByTargetIdAndType(eventActivityIdList, LinkType.ACTIVITY);
        Map<Integer, Long> browseCountMap = userBrowseLinkService.mapByTargetIdAndType(eventActivityIdList, LinkType.ACTIVITY);
        // 用户是否有点赞收藏
        Map<Integer, UserLikeLink> userLikeMap = userLikeLinkService.mapByUserTargetAndType(eventActivityIdList, LinkType.ACTIVITY, userId);
        Map<Integer, UserCollectionLink> userCollectionMap = userCollectionLinkService.mapByUserTargetAndType
                (eventActivityIdList, LinkType.ACTIVITY, userId);
        // 查询景点对应的乡村
        List<Integer> rusticIdList = eventActivityList.stream().map(EventActivity::getRusticId).collect(Collectors.toList());
        Map<Integer, Rustic> rusticMap = rusticService.mapByIdIn(rusticIdList);
        // 类型查询
        List<Category> categoryList = categoryService.listByType(CategoryType.ACTIVITY);
        Map<Integer, Category> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, b -> b));
        return eventActivityList.stream().map(item -> {
            EventActivityWebListVO activityWebListVO = new EventActivityWebListVO(item);
            // 得到点赞的数量
            if (likeCountMap.get(item.getId()) != null) {
                activityWebListVO.setLikeCount(likeCountMap.get(item.getId()));
            }
            // 收藏的数量
            if (collectionCountMap.get(item.getId()) != null) {
                activityWebListVO.setCollectionCount(collectionCountMap.get(item.getId()));
            }
            // 浏览数量
            if (browseCountMap.get(item.getId()) != null) {
                activityWebListVO.setBrowseCount(browseCountMap.get(item.getId()));
            }
            // 用户是否点赞
            if (userLikeMap.get(item.getId()) != null) {
                activityWebListVO.setLike(true);
            }
            // 用户是否收藏
            if (userCollectionMap.get(item.getId()) != null) {
                activityWebListVO.setCollection(true);
            }
            // 填充对应的乡村名称
            Rustic rustic = rusticMap.get(item.getRusticId());
            if (rustic != null) {
                activityWebListVO.setRusticName(rustic.getName());
            }
            // 类型
            Category category = categoryMap.get(item.getType());
            if (category != null) {
                activityWebListVO.setTypeName(category.getName());
            }
            return activityWebListVO;
        }).collect(Collectors.toList());
    }

    @Override
    public LambdaQueryWrapper<EventActivity> toUserListWrapper(EventActivityUserListQuery query) {
        LambdaQueryWrapper<EventActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EventActivity::getRusticId, query.getRusticId());
        queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getName()), EventActivity::getName, query.getName());
        queryWrapper.eq(query.getType() > 0, EventActivity::getType, query.getType());
        queryWrapper.eq(EventActivity::getStatus, DisableStatus.NORMAL.getValue());
//        queryWrapper.gt(query.getStartStartTime() != null, EventActivity::getStartTime, query.getStartStartTime());
//        queryWrapper.lt(query.getEndStartTime() != null, EventActivity::getStartTime, query.getEndStartTime());
//        queryWrapper.gt(query.getStartEndTime() != null, EventActivity::getEndTime, query.getStartEndTime());
//        queryWrapper.lt(query.getEndEndTime() != null, EventActivity::getEndTime, query.getEndEndTime());
        queryWrapper.orderByDesc(EventActivity::getSort);
        queryWrapper.orderByDesc(EventActivity::getUpdateTime);
        return queryWrapper;
    }

    private void checkAddOrUpdate(EventActivity eventActivity) {
        // 关联乡村是否存在
        Rustic rustic = rusticService.getById(eventActivity.getRusticId());
        if (rustic == null) {
            throw new JzRuntimeException(RusticService.RUSTIC_NOT_EXIST);
        }
        // 分类id是否存在
        Category category = categoryService.getByIdAndType(eventActivity.getType(), CategoryType.ACTIVITY);
        if (category == null) {
            throw new JzRuntimeException(CategoryService.CATEGORY_NOT_EXIST);
        }
        // 判断活动时间开始在结束的前面
        int compare = eventActivity.getStartTime().compareTo(eventActivity.getEndTime());
        if (compare > 0) {
            throw new JzRuntimeException("开始时间不能比结束时间晚");
        }
    }

    @Override
    public void add(EventActivity eventActivity) {
        // 校验参数
        this.checkAddOrUpdate(eventActivity);
        // fixme 直接发布
        eventActivity.setStatus(DisableStatus.NORMAL.getValue());
        eventActivity.setPublishTime(new Date());
        this.save(eventActivity);
    }

    @Override
    public EventActivityVO getDetailById(int id) {
        EventActivity eventActivity = this.getById(id);
        if (eventActivity == null) {
            throw new JzRuntimeException(EventActivityService.EVENT_ACTIVITY_NOT_EXIST);
        }
        EventActivityVO eventActivityVO = new EventActivityVO(eventActivity);
        List<Integer> sysAdminListId = new ArrayList<>();
        sysAdminListId.add(eventActivity.getCreatorId());
        sysAdminListId.add(eventActivity.getModifierId());
        Map<Integer, SysAdmin> sysAdminMap = sysAdminService.mapByIdList(sysAdminListId);
        eventActivityVO.setCreator(sysAdminMap.get(eventActivity.getCreatorId()) != null ?
                sysAdminMap.get(eventActivity.getCreatorId()).getUsername() : "");
        eventActivityVO.setModifier(sysAdminMap.get(eventActivity.getModifierId()) != null ?
                sysAdminMap.get(eventActivity.getModifierId()).getUsername() : "");
        return eventActivityVO;
    }

    @Override
    public void update(EventActivityUpdateDTO eventActivityUpdateDTO) {
        EventActivity eventActivity = this.getById(eventActivityUpdateDTO.getId());
        if (eventActivity == null) {
            throw new JzRuntimeException(EventActivityService.EVENT_ACTIVITY_NOT_EXIST);
        }
        BeanUtils.copyProperties(eventActivityUpdateDTO, eventActivity);
        this.checkAddOrUpdate(eventActivity);
        // fixme 直接发布
        eventActivity.setStatus(DisableStatus.NORMAL.getValue());
        eventActivity.setPublishTime(new Date());
        this.updateById(eventActivity);
    }

    @Override
    public int enabled(int id) {
        EventActivity eventActivity = this.getById(id);
        if (eventActivity == null) {
            throw new JzRuntimeException(EventActivityService.EVENT_ACTIVITY_NOT_EXIST);
        }
        if (DisableStatus.isDisable(eventActivity.getStatus())) {
            // 要上架的
            eventActivity.setPublishTime(new Date());
        }
        eventActivity.setStatus(DisableStatus.negate(eventActivity.getStatus()));
        this.updateById(eventActivity);
        return eventActivity.getStatus();
    }

    @Override
    public EventActivityWebVO getByIdToWeb(int id) {
        EventActivity eventActivity = this.getById(id);
        if (eventActivity == null) {
            throw new JzRuntimeException("风貌展示详情不存在!");
        }
        EventActivityWebVO eventActivityWebVO = new EventActivityWebVO(eventActivity);
        // 获取分类
        Category category = categoryService.getByIdAndType(eventActivity.getType(), CategoryType.ACTIVITY);
        eventActivityWebVO.setTypeName(category != null ? category.getName() : "");
        // 获取乡村名
        Rustic rustic = rusticService.getById(eventActivity.getRusticId());
        eventActivityWebVO.setRusticName(rustic != null ? rustic.getName() : "");
        return eventActivityWebVO;
    }
}
